using System.Data.SqlClient;
using System.Collections.Generic;

using ROC.Resources.Library.Data;
using ROC.Resources.Library.Data.SQL2005;

using MoneyManagerPro.Resources.Repository.Users;

namespace MoneyManagerPro.Resources.Repository.Users
{
    public class UserRepository : SqlRepository<MoneyManagerPro.Business.Entities.User>
    {
        private string mDataBaseName;

        public UserRepository(string databaseName)
            : base(databaseName)
        {
            this.mDataBaseName = databaseName;
        }

        private void HandleSqlException(SqlException ex, ROC.Resources.Library.Data.Generic.IDbToBusinessEntityNameMapper mapper)
        {
            if (ex.Number == ErrorCodes.SqlUserRaisedError)
            {
                switch (ex.State)
                {
                    case ErrorCodes.ValidationError:
                        string[] messageParts = ex.Errors[0].Message.Split(':');
                        throw new RepositoryValidationException(
                            mapper.MapDbParameterToBusinessEntityProperty(messageParts[0]),
                            messageParts[1], ex);

                    case ErrorCodes.ConcurrencyViolationError:
                        throw new ConcurrencyViolationException(ex.Message, ex);

                }
            }

            throw new RepositoryFailureException(ex);
        }

        #region Create methods

        public void Add(MoneyManagerPro.Business.Entities.User user)
        {
            UserInsertFactory insertFactory = new UserInsertFactory();

            try
            {
                base.Add(insertFactory, user);
            }
            catch (SqlException ex)
            {
                HandleSqlException(ex, insertFactory);
            }
        }

        #endregion

        #region Read methods

        public MoneyManagerPro.Business.Entities.User GetUserById(System.Int32 id)
        {
            ISelectionFactory<System.Int32> selectionFactory = new GetUserByIdSelectionFactory();

            try
            {
                return base.FindOne(selectionFactory, new UserColumnFactory(), id);
            }
            catch (SqlException ex)
            {
                HandleSqlException(ex, selectionFactory);
            }

            return new MoneyManagerPro.Business.Entities.User();
        }

        public List<MoneyManagerPro.Business.Entities.User> GetAllFromUsers()
        {
            ISelectionFactory<NullableIdentity> selectionFactory = new GetAllFromUsersSelectionFactory();

            try
            {
                NullableIdentity nullableIdentity = new NullableIdentity();
                return base.Find(selectionFactory, new UserColumnFactory(), nullableIdentity);
            }
            catch (SqlException ex)
            {
                HandleSqlException(ex, selectionFactory);
            }

            return new List<MoneyManagerPro.Business.Entities.User>();
        }

        #endregion

        #region Update methods

        public void Update(MoneyManagerPro.Business.Entities.User user)
        {
            UserUpdateFactory updateFactory = new UserUpdateFactory();
            try
            {
                base.Update(updateFactory, user);
            }
            catch (SqlException ex)
            {
                HandleSqlException(ex, updateFactory);
            }
        }

        #endregion

        #region Delete methods

        public void Remove(int id)
        {
            IDeleteFactory<System.Int32> deleteFactory = new UserDeleteFactory();

            try
            {
                base.Remove(deleteFactory, id);
            }
            catch (SqlException ex)
            {
                HandleSqlException(ex, deleteFactory);
            }
        }

        #endregion

    }
}
